"use strict";
cc._RF.push(module, 'd2e42voSrJBvqyjvkrk/7Zd', 'GlobalEvent');
// script/original/Standar/Event/GlobalEvent.js

"use strict";

//事件 的 回调（回调函数和目标对象）
var callFuncs = cc.Class({
  name: "callFuncs",
  properties: {
    callback: null,
    target: null,
    once: false
  }
}); //全局事件（事件名和事件回调事件回调数组，因为同一个事件可能有多个节点在监听，所以事件回调数组存放所有需要调用的函数以及调用函数的对象）

var globalEvent = cc.Class({
  name: "globalEvent",
  properties: {
    eventName: "",
    callbacks: {
      "default": [],
      type: callFuncs
    }
  }
});
var eventOrder = new cc.Enum({
  TOP_TO_BOTTOM: 0,
  BOTTOM_TO_TOP: 1
});
cc.Class({
  "extends": cc.Component,
  properties: {
    _eventList: {
      "default": [],
      type: globalEvent
    },
    sendOrder: {
      "default": eventOrder.TOP_TO_BOTTOM,
      type: eventOrder
    },
    _sendList: [],
    _removeList: [],
    _isStart: false
  },
  // use this for initialization
  onLoad: function onLoad() {
    //把GlobalEvent属性添加到director
    cc.director.GlobalEvent = this;
  },
  //所有在onLoad里添加的监听器，统一在start阶段进行派送，这样做的原因是，假设监听事件和派送事件都在onLoad进行，有可能派送事件比监听事件先发生，此次事件派送就会失效
  start: function start() {
    this._isStart = true;

    for (var i = 0; i < this._sendList.length; i++) {
      var event = this._sendList[i];
      this.sendEvent(event.eventName, event.data);
    } //start阶段派送完所有事件后，删除临时的事件列表


    this._sendList.splice(0, this._sendList.length);

    this._sendList.length > 0 ? this._sendList = [] : null;
  },
  //添加监听器（事件名，回调函数，目标对象，是否是一次性的事件）
  _monitor: function _monitor(eventName, callback, target, once) {
    //新建一个事件回调对象保存回调函数和目标对象
    var call = new callFuncs(); //回调函数是否是函数对象

    callback instanceof Function ? call.callback = callback : cc.error("event callback not a function"); //目标对象存不存在

    target ? call.target = target : cc.error("global event is not have target"); //是否是一次性事件

    call.once = once; //如果事件列表不为空，则查找是否  已有  和  将要添加的事件    相同事件名的事件

    if (this._eventList.length > 0) {
      //遍历事件列表
      for (var i = 0; i < this._eventList.length; i++) {
        //如果已有相同事件
        if (this._eventList[i].eventName === eventName) {
          //则只增加事件回调
          this._eventList[i].callbacks.push(call); //不再查找


          return; //如果没有找到相同的事件
        } else if (i === this._eventList.length - 1) {
          //新建全局事件
          var event = new globalEvent(); //事件名是否存在

          eventName ? event.eventName = eventName : cc.error("event name is null"); //把创建好的事件回调添加到此次事件

          event.callbacks.push(call); //把此次事件添加到事件列表

          this._eventList.push(event);

          return;
        }
      } //如果事件列表为空，则添加一个全局事件    

    } else {
      var event = new globalEvent();
      eventName ? event.eventName = eventName : cc.error("event name is null");
      event.callbacks.push(call);

      this._eventList.push(event);
    }
  },
  //发送事件
  sendEvent: function sendEvent(eventName, data) {
    //如果还在onLoad阶段，保存要发送的事件，直接退出，在start阶段才开始发送事件
    if (!this._isStart) {
      this._sendList.push({
        eventName: eventName,
        data: data
      });

      return;
    } //cc.log("send event name is " + eventName);
    //遍历事件列表


    for (var i = 0; i < this._eventList.length; i++) {
      //如果事件列表里有此次事件（任意一个对象添加了监听器，都会把事件存放在事件列表）
      if (this._eventList[i].eventName === eventName) {
        //根据自定义的层级顺序发送事件
        if (this.sendOrder === eventOrder.BOTTOM_TO_TOP) {
          //遍历 事件 的 回调
          for (var j = this._eventList[i].callbacks.length - 1; j >= 0; j--) {
            //停止传递此次事件
            var stop = function stop() {
              goOn = false;
            };

            //目标对象
            var target = this._eventList[i].callbacks[j].target; //回调函数

            var callback = this._eventList[i].callbacks[j].callback; //是否继续传递此次事件

            var goOn = true;
            ; //事件回调的参数（自定义的数据，停止传递事件的函数）

            var event = {
              data: data,
              stopSend: stop
            }; //调用回调函数

            callback.call(target, event); //如果停止了事件的传递

            if (!goOn) {
              //不再触发 事件回调
              break;
            } //如果删除了当前事件回调，则不执行后面的操作，而继续循环


            if (!this._eventList[i].callbacks[j]) {
              continue;
            } //如果当前的 事件回调 是一次性的，回调完成就删除当前这个 事件回调


            if (this._eventList[i].callbacks[j].once) {
              this._eventList[i].callbacks.splice(j, 1); //因为这里的顺序是从后到前，所以不管当前事件回调有没有被删除，j继续指向前一个事件回调

            }
          }
        } else if (this.sendOrder === eventOrder.TOP_TO_BOTTOM) {
          for (var _j = 0; _j < this._eventList[i].callbacks.length; _j++) {
            var _stop = function _stop() {
              goOn = false;
            };

            var _callback = this._eventList[i].callbacks[_j].callback;
            var _target = this._eventList[i].callbacks[_j].target;
            var goOn = true;
            ;
            var _event = {
              data: data,
              stopSend: _stop
            };

            _callback.call(_target, _event);

            if (!goOn) {
              break;
            }

            if (!this._eventList[i].callbacks[_j]) {
              _j -= 1;
              continue;
            }

            if (this._eventList[i].callbacks[_j].once) {
              this._eventList[i].callbacks.splice(_j, 1); //这里的顺序是从前到后，如果删除一个元素后，后面每个元素的下标都会-1；


              _j -= 1;
            }
          }
        } //找到事件并触发完成后，不再继续查找 


        return;
      }
    }
  },
  //添加一次性事件
  addMonitorOnce: function addMonitorOnce(eventName, callback, target) {
    this._monitor(eventName, callback, target, true);
  },
  //添加普通事件
  addMonitor: function addMonitor(eventName, callback, target) {
    this._monitor(eventName, callback, target, false);
  },
  //通过事件名和target移除一个监听器
  removeMonitor: function removeMonitor(eventName, target) {
    for (var i = 0; i < this._eventList.length; i++) {
      //找到事件
      if (this._eventList[i].eventName === eventName) {
        for (var j = 0; j < this._eventList[i].callbacks.length; j++) {
          //找到事件回调
          if (this._eventList[i].callbacks[j].target === target) {
            //移除回调对象上的监听器
            this._eventList[i].callbacks.splice(j, 1);
          }
        }
      }
    }
  },
  //移除所有事件监听
  removeAllMonitor: function removeAllMonitor() {
    this._eventList.splice(0, this._eventList.length);

    this._eventList.length > 0 ? this._eventList = [] : null;
  } // called every frame, uncomment this function to activate update callback
  // update: function (dt) {
  // },

});

cc._RF.pop();